const msgpack = require('./node_modules/msgpack-lite');
const config = require('./config');
const vscode = require('vscode');
const exp = require('constants');
const path = require('path');
const fs = require('fs');

class utils {
    static postData(url, port, content) {
        return new Promise((rs) => {
            const http = require('http');
            const options = {
                hostname: url,
                port: port,
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Content-Length': Buffer.byteLength(content)
                },
            };
            const req = http.request(options, (res) => {
                res.setEncoding('utf8');
                let data = "";
                res.on('data', (chunk) => {
                    data += chunk;
                });
                res.on('end', () => {
                    rs(data)
                });
            });
            req.on('error', (e) => {
                console.error(`problem with request: ${e.message}`);
            });
            req.write(content);
            req.end();
        })
    }
    static postHost(content) {
        return new Promise((res) => {
            this.postData(config.url, config.port, msgpack.encode(content).toString("hex")).then(v => {
                res(msgpack.decode(Buffer.from(v, "hex")));
            });
        })
    }
    static requestHttp(url) {
        return new Promise((res) => {
            let http = require("http");
            let req = http.request(url, (rq) => {
                let data = "";
                rq.on("data", (str) => {
                    data += str;
                })
                rq.on("end", () => {
                    res(data);
                });
            })
            req.end();
        })

    }
    static packDir(target, out) {
        return new Promise((res) => {
            const _7z = require('7zip-min');
            _7z.pack(target, out, v => res())
        })
    }
    static unPackDir(target, out) {
        return new Promise((res) => {
            const _7z = require('7zip-min');
            _7z.unpack(target, out, v => res())
        })
    }
    static async publishModule() {
        let workspaceFolder = vscode.workspace.workspaceFolders[0]?.uri?.fsPath;
        if (!workspaceFolder) return vscode.window.showErrorMessage("需要先打开工程目录");
        if (!config.token) return vscode.window.showErrorMessage("需要先登录账号才能发布");
        let lst = fs.readdirSync(workspaceFolder, {}).filter(v => {
            let fileStat = fs.statSync(path.join(workspaceFolder, v))
            return fileStat.isDirectory() && v[0] != ".";
        });
        let moduleName = await vscode.window.showQuickPick(lst, { placeHolder: "选择模块目录,模块名以目录名命名" });
        if (!moduleName) return;
        let libPath = path.join(workspaceFolder, moduleName);
        await this.packDir(libPath, __dirname + "/lib.7z");
        let rs = await this.postHost({ cmd: "pubishModule", token: config.token, moduleName: moduleName, file: fs.readFileSync(__dirname + "/lib.7z") })
        if (rs.success == 1) {
            vscode.window.showInformationMessage("发布成功");
        } else {
            vscode.window.showErrorMessage(`模块名称已经使用${moduleName}`,);
        }
        fs.rmSync(__dirname + "/lib.7z");
    }
    static async getModuleList() {
        let rs = await this.postHost({ cmd: "getModuleList" });
        if (rs && rs.success == 1) {
            let lst = rs.list.map(v => {
                v.description = `${v.description || "没有详细说明"} 发布者:${v.publisher} 更新日期${new Date(+v.version).toLocaleString()} 点赞数:0`
                return v;
            });
            let opt = await vscode.window.showQuickPick(lst, { placeHolder: "选择一个模块进行进一步处理" });
            if (!opt) return
            let tab = [];
            let isExistsVertionFile = fs.existsSync(`${__dirname}/luaLibs/${opt.label}/version.txt`);
            let canUpdate = true;
            let isUpdate = false;
            if (isExistsVertionFile) {
                let version = fs.readFileSync(`${__dirname}/luaLibs/${opt.label}/version.txt`) || "";
                if (+opt.version == +version) canUpdate = false;
                isUpdate = +opt.version != +version
            }
            if (canUpdate) {
                tab.push({
                    label: isUpdate ? "更新" : "安装",
                    description: "",
                    func: async () => {
                        let rs = await this.postHost({ cmd: "downLoadModule", moduleName: opt.label });
                        if (rs) {
                            this.deleteall(__dirname + "/luaLibs/" + opt.label);
                            fs.writeFileSync(__dirname + "/lib.7z", rs.file);
                            await this.unPackDir(__dirname + "/lib.7z", __dirname + "/luaLibs");
                            fs.writeFileSync(`${__dirname}/luaLibs/${opt.label}/version.txt`, opt.version);
                            vscode.window.showInformationMessage(`更新库 ${opt.label}成功, 需要重新加载ide`, "重新加载").then(v => {
                                if (v) {
                                    vscode.commands.executeCommand("workbench.action.reloadWindow");
                                }
                            })
                            fs.rmSync(__dirname + "/lib.7z");
                        }
                    }
                })
            }
            tab.push(
                {
                    label: "点赞",
                    description: ""
                },
                {
                    label: "教程/案例",
                    description: ""
                },
                {
                    label: "反馈/建议",
                    description: ""
                }
            )
            if (isExistsVertionFile) {
                tab.push(
                    {
                        label: "从库中移除",
                        description: "",
                        func: () => {
                            this.deleteall(__dirname + "/luaLibs/" + opt.label);
                            vscode.window.showInformationMessage(`删除库 ${opt.label}成功, 需要重新加载ide`, "重新加载").then(v => {
                                if (v) {
                                    vscode.commands.executeCommand("workbench.action.reloadWindow");
                                }
                            })
                        }
                    }
                )
            }
            let opt2 = await vscode.window.showQuickPick(tab);
            if (!opt2) return;
            opt2.func && opt2.func();
        }

    }
    static login() {
        if (config.token) {
            config.token = null;
            config.username = null;
            vscode.window.showInformationMessage("账号已注销");
            return;
        }
        vscode.window.showInputBox({
            prompt: "请输入账号",
            placeHolder: "账号名",
        }).then(username => {
            if (username) {
                vscode.window.showInputBox({
                    prompt: "请输入密码",
                    placeHolder: "密码",
                    password: true
                }).then(password => {
                    if (password) {
                        this.postHost({ cmd: "login", username: username, password: password }).then(v => {
                            if (v.success == 1) {
                                vscode.window.showInformationMessage("登录成功");
                                config.token = v.token;
                                config.username = username;
                                if (!v.hasEmail) {
                                    vscode.window.showInputBox({
                                        prompt: "请完善一下你的邮箱",
                                        placeHolder: "邮箱",
                                        password: true
                                    }).then(email => {
                                        if (email) {
                                            this.postHost({ cmd: "updateEmail", token: config.token, email: email }).then(v => {
                                                if (v.success == 1) {
                                                    vscode.window.showInformationMessage("邮箱更改成功");
                                                } else {
                                                    vscode.window.showErrorMessage(v.msg);
                                                }
                                            })
                                        }
                                    })
                                }
                            } else {
                                vscode.window.showErrorMessage("登录失败,密码不正确");
                            }
                        })
                    }
                })
            }
        })
    }
    static build() {

    }
    static setup() {

    }
    static uiMgr() {

    }
    static uiMgr() {

    }
    static example() {

    }
    static tools() {

    }
    static create() {
        let workspaceFolder = vscode.workspace.workspaceFolders[0]?.uri?.fsPath;
        if (!workspaceFolder) return vscode.window.showErrorMessage("需要先打开工程目录");
        let dirname = __dirname.replace(/\\/g,"/")
        let settings = {
            "Lua.telemetry.enable": true,
            "Lua.runtime.version": "LuaJIT",
            "Lua.workspace.library": [
                `${dirname}/luaLibs`
            ],
            "lua.debug.settings.luaVersion": "jit",
            "lua.debug.settings.console": "internalConsole",
            "lua.debug.settings.path": `${dirname}/luaLibs/?.lua`,
            "Lua.runtime.path": [
                "?.lua",
                "?/init.lua",
            ]
        };
        let launchCode = {
            "version": "0.2.0",
            "configurations": [
                {
                    "type": "lua",
                    "request": "launch",
                    "name": "Debug",
                    "program": `${dirname}/luaLibs/luajit-stdlib/run.lua`,
                    "stopOnEntry": false,
                    "arg": [
                        "${file}"
                    ]
                }
            ]
        };
        if (!fs.existsSync(workspaceFolder + `/.vscode`)) fs.mkdirSync(workspaceFolder + `/.vscode`);
        fs.writeFileSync(workspaceFolder + `/.vscode/settings.json`, JSON.stringify(settings, null, "\t"));
        fs.writeFileSync(workspaceFolder + `/.vscode/launch.json`, JSON.stringify(launchCode, null, "\t"));
        //if (!fs.existsSync(`main.lua`)) fs.writeFileSync(`main.lua`, `console.log("helloword")`);
    }
    static deleteall(path) {
        var files = [];
        if (fs.existsSync(path)) {
            files = fs.readdirSync(path);
            files.forEach((file, index) => {
                var curPath = path + "/" + file;
                if (fs.statSync(curPath).isDirectory()) { // recurse
                    this.deleteall(curPath);
                } else { // delete file
                    fs.unlinkSync(curPath);
                }
            });
            fs.rmdirSync(path);
        }
    };
}
module.exports = utils;